home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / liboctave / Range.cc < prev    next >
C/C++ Source or Header  |  1996-12-20  |  6KB  |  250 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include <cfloat>
  32. #include <climits>
  33. #include <cmath>
  34.  
  35. #include <iostream.h>
  36.  
  37. #include "Range.h"
  38. #include "dMatrix.h"
  39. #include "lo-mappers.h"
  40. #include "lo-utils.h"
  41.  
  42. bool
  43. Range::all_elements_are_ints (void) const
  44. {
  45.   // If the base and increment are ints, the final value in the range
  46.   // will also be an integer, even if the limit is not.
  47.  
  48.   return (! (xisnan (rng_base) || xisnan (rng_inc))
  49.       && (double) NINT (rng_base) == rng_base
  50.       && (double) NINT (rng_inc) == rng_inc);
  51. }
  52.  
  53. Matrix
  54. Range::matrix_value (void) const
  55. {
  56.   Matrix retval;
  57.  
  58.   if (rng_nelem > 0)
  59.     {
  60.       retval.resize (1, rng_nelem);
  61.       double b = rng_base;
  62.       double increment = rng_inc;
  63.       for (int i = 0; i < rng_nelem; i++)
  64.     retval.elem (0, i) = b + i * increment;
  65.     }
  66.  
  67.   return retval;
  68. }
  69.  
  70. // NOTE: max and min only return useful values if nelem > 0.
  71.  
  72. double
  73. Range::min (void) const
  74. {
  75.   double retval = 0.0;
  76.   if (rng_nelem > 0)
  77.     {
  78.       if (rng_inc > 0)
  79.     retval = rng_base;
  80.       else
  81.     retval = rng_base + (rng_nelem - 1) * rng_inc;
  82.     }
  83.   return retval;
  84. }
  85.  
  86. double
  87. Range::max (void) const
  88. {
  89.   double retval = 0.0;
  90.   if (rng_nelem > 0)
  91.     {
  92.       if (rng_inc > 0)
  93.     retval = rng_base + (rng_nelem - 1) * rng_inc;
  94.       else
  95.     retval = rng_base;
  96.     }
  97.   return retval;
  98. }
  99.  
  100. void
  101. Range::sort (void)
  102. {
  103.   if (rng_base > rng_limit && rng_inc < 0.0)
  104.     {
  105.       double tmp = rng_base;
  106.       rng_base = min ();
  107.       rng_limit = tmp;
  108.       rng_inc = -rng_inc;
  109.     }
  110. }
  111.  
  112. void
  113. Range::print_range (void)
  114. {
  115.   cerr << "Range: rng_base = " << rng_base
  116.        << " rng_limit " << rng_limit
  117.        << " rng_inc " << rng_inc
  118.        << " rng_nelem " << rng_nelem << "\n";
  119. }
  120.  
  121. ostream&
  122. operator << (ostream& os, const Range& a)
  123. {
  124.   double b = a.base ();
  125.   double increment = a.inc ();
  126.   int num_elem = a.nelem ();
  127.  
  128.   for (int i = 0; i < num_elem; i++)
  129.     os << b + i * increment << " ";
  130.  
  131.   os << "\n";
  132.  
  133.   return os;
  134. }
  135.  
  136. istream&
  137. operator >> (istream& is, Range& a)
  138. {
  139.   is >> a.rng_base;
  140.   if (is)
  141.     {
  142.       is >> a.rng_limit;
  143.       if (is)
  144.     {
  145.       is >> a.rng_inc;
  146.       a.rng_nelem = a.nelem_internal ();
  147.     }
  148.     }
  149.  
  150.   return is;
  151. }
  152.  
  153. Range
  154. operator - (const Range& r)
  155. {
  156.   return Range (-r.base (), -r.limit (), -r.inc ());
  157. }
  158.  
  159. // C  See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5.
  160. // C
  161. // C===Tolerant FLOOR function.
  162. // C
  163. // C    X  -  is given as a Double Precision argument to be operated on.
  164. // C          It is assumed that X is represented with M mantissa bits.
  165. // C    CT -  is   given   as   a   Comparison   Tolerance   such   that
  166. // C          0.LT.CT.LE.3-SQRT(5)/2. If the relative difference between
  167. // C          X and A whole number is  less  than  CT,  then  TFLOOR  is
  168. // C          returned   as   this   whole   number.   By  treating  the
  169. // C          floating-point numbers as a finite ordered set  note  that
  170. // C          the  heuristic  EPS=2.**(-(M-1))   and   CT=3*EPS   causes
  171. // C          arguments  of  TFLOOR/TCEIL to be treated as whole numbers
  172. // C          if they are  exactly  whole  numbers  or  are  immediately
  173. // C          adjacent to whole number representations.  Since EPS,  the
  174. // C          "distance"  between  floating-point  numbers  on  the unit
  175. // C          interval, and M, the number of bits in X'S mantissa, exist
  176. // C          on  every  floating-point   computer,   TFLOOR/TCEIL   are
  177. // C          consistently definable on every floating-point computer.
  178. // C
  179. // C          For more information see the following references:
  180. // C    (1) P. E. Hagerty, "More On Fuzzy Floor And Ceiling," APL  QUOTE
  181. // C        QUAD 8(4):20-24, June 1978. Note that TFLOOR=FL5.
  182. // C    (2) L. M. Breed, "Definitions For Fuzzy Floor And Ceiling",  APL
  183. // C        QUOTE QUAD 8(3):16-23, March 1978. This paper cites FL1 through
  184. // C        FL5, the history of five years of evolutionary development of
  185. // C        FL5 - the seven lines of code below - by open collaboration
  186. // C        and corroboration of the mathematical-computing community.
  187. // C
  188. // C  Penn State University Center for Academic Computing
  189. // C  H. D. Knoble - August, 1978.
  190.  
  191. static inline double
  192. tfloor (double x, double ct)
  193. {
  194. // C---------FLOOR(X) is the largest integer algebraically less than
  195. // C         or equal to X; that is, the unfuzzy FLOOR function.
  196.  
  197. //  DINT (X) = X - DMOD (X, 1.0);
  198. //  FLOOR (X) = DINT (X) - DMOD (2.0 + DSIGN (1.0, X), 3.0);
  199.  
  200. // C---------Hagerty's FL5 function follows...
  201.  
  202.   double q = 1.0;
  203.  
  204.   if (x < 0.0)
  205.     q = 1.0 - ct;
  206.  
  207.   double rmax = q / (2.0 - ct);
  208.  
  209.   double t1 = 1.0 + floor (x);
  210.   t1 = (ct / q) * (t1 < 0.0 ? -t1 : t1);
  211.   t1 = rmax < t1 ? rmax : t1;
  212.   t1 = ct > t1 ? ct : t1;
  213.   t1 = floor (x + t1);
  214.  
  215.   if (x <= 0.0 || (t1 - x) < rmax)
  216.     return t1;
  217.   else
  218.     return t1 - 1.0;
  219. }
  220.  
  221. static inline double
  222. tceil (double x, double ct)
  223. {
  224.   return -tfloor (-x, ct);
  225. }
  226.  
  227. static inline double
  228. round (double x, double ct)
  229. {
  230.   return tfloor (x+0.5, ct);
  231. }
  232.  
  233. int
  234. Range::nelem_internal (void) const
  235. {
  236.   double ct = 3.0 * DBL_EPSILON;
  237.  
  238.   double tmp = tfloor ((rng_limit - rng_base + rng_inc) / rng_inc, ct);
  239.  
  240.   int n_intervals = (int) (tmp > 0.0 ? tmp : 0);
  241.  
  242.   return (n_intervals >= INT_MAX - 1) ? -1 : n_intervals;
  243. }
  244.  
  245. /*
  246. ;;; Local Variables: ***
  247. ;;; mode: C++ ***
  248. ;;; End: ***
  249. */
  250.